/* 
 * DateHelper.java created at: 2005-3-8 10:56:49 by elvis
 * $Id: DateHelper.java,v 1.4 2007/05/14 02:48:13 czqcs Exp $ 
 */

package net.bingosoft.common.util;

import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import net.bingosoft.common.BeanHelper;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * 
 * @author elvis
 */
public final class DateHelper {
    
    private static final Log log = LogFactory.getLog(DateHelper.class);
    
    //private constructor.
    private DateHelper() { }

    /** 格式：年－月－日 小时：分钟：秒 <br>"yyyy-MM-dd HH:mm:ss"*/
    public static final String LONG_DATETIME_FORMAT = "yyyy-MM-dd HH:mm:ss";

    /**格式：年－月－日 <br>"yyyy-MM-dd"*/
    public static final String LONG_DATE_FORMAT = "yyyy-MM-dd";

    /**格式：月－日<br>"MM-dd"*/
    public static final String SHORT_DATE_FORMAT = "MM-dd";

    /**格式：小时：分钟：秒 <br>"HH:mm:ss"*/
    public static final String LONG_TIME_FORMAT = "HH:mm:ss";

    /**
     * 把符合日期格式的字符串转换为日期类型
     * 
     * @param date 日期字符串
     * @param format 转换格式
     * @return Date 日期类型,如果转换不成功返回null
     */
    public static Date toDate(String date, String format) {
        ParsePosition pos = new ParsePosition(0);
        Date d = toDate(date,format,pos);
        if(null != d && pos.getIndex() != date.length()){
            d = null;
        }
        return d;
    }

    /**
     * 把符合日期格式的字符串转换为日期类型
     * @param date  日期字符串
     * @param format 转换格式
     * @param pos @see ParsePosition
     * @return Date 日期类型,如果转换不成功返回null
     */
    public static Date toDate(String date, String format, ParsePosition pos) {
        if (date == null) {
            return null;
        }
        Date d = null;
        SimpleDateFormat formater = new SimpleDateFormat(format);
        try {
            formater.setLenient(false);
            d = formater.parse(date, pos);
        } catch (Exception e) {
            log.error(e);
            d = null;
        }
        return d;
    }
    
    /**
     * 分别使用三种格式转换字符串为java.util.Date类型
     * @param date
     * @return
     */
    public static Date toDate(String date){
        Date d = toDate(date,LONG_DATE_FORMAT);
        if(null == d){
            d = toDate(date,LONG_DATETIME_FORMAT);
        }
        if(null == d){
            d = toDate(date,LONG_TIME_FORMAT);
        }
        return d;
    }
    
    /**
     * 判断给定的字符串是否日期，日期格式为LONG_DATE_FORMAT
     * @param date 日期字符串
     * @return 是日期返回true,否则返回false
     */
    public static boolean isDate(String date) {
        return isDate(date, LONG_DATE_FORMAT);
    }

    /**
     * 判断给定的字符串是否与指定的日期格式吻合
     * @param date  日期字符串
     * @param format 日期格式
     * @return 符合返回true，否则返回false
     */
    public static boolean isDate(String date, String format) {
        if (null == date) {
            return false;
        }

        Date d = null;
        ParsePosition pos = new ParsePosition(0);
        d = toDate(date, format, pos);
        return (null == d ? false : true) && (pos.getIndex() == date.length());
    }

    /**
     * 把日期转换为字符串
     * @param date  日期
     * @param format 转换格式
     * @return 日期字符串
     */
    public static String toString(Date date, String format) {
        if (date == null) {
            return "";
        }
        String result = null;
        SimpleDateFormat formater = new SimpleDateFormat(format);
        try {
            result = formater.format(date);
        } catch (Exception e) {
            log.error(e);
        }
        return null == result ? "" : result;
    }

    /**
     * 返回当前日期,小时，分钟，秒数,毫秒数都为0
     * 
     * @return Date
     */
    public static Date currentDate() {
        Date date = new Date();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY,0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }
	/**
	 * 格式化日期,根据时分秒是否为空自动选择使用格式 yyyy-MM-dd 或 yyyy-MM-dd HH:mm:ss
	 * @param date
	 * @return
	 */
	public static String formatDate(Date date){
		return BeanHelper.formatDate(date);
	}
    
    /**
     * 返回属于指定日期的最早的时间
     * @param date
     * @return
     */
    public static Date getEarliestTime(Date date){
         Calendar calendar = Calendar.getInstance();
         calendar.setTime(date);
         calendar.set(Calendar.HOUR_OF_DAY,0);
         calendar.set(Calendar.MINUTE, 0);
         calendar.set(Calendar.SECOND, 0);
         return calendar.getTime();
    }
    /**
     * 返回属于指定日期最晚的时间,如传入日期为2007-08-12 会返回一个时间 2007-08-12 23:59:59
     * @param date
     * @return
     */
    public static Date getLatestTime(Date date){
    	Calendar calendar = Calendar.getInstance();
    	calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY,23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        return calendar.getTime();
    }

    /**
     * get the current time, like now() function in vb.
     * 
     * @return Date
     */
    public static Date currentTime() {
        return new Date();
    }

    /**
     * 获取某年某月的天数
     * @param year int 年
     * @param month int 月份[1-12]
     * @return int 天数
     */
    public static int getDaysOfMonth(int year, int month) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(year, month - 1, 1);
        return calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
    }

    /**
     * 获取指定日期所在的周的第一天的日期，星期天为第一天
     * @param weekDate 周里任意一天的日期
     * @return Date 第一天的日期
     */
    public static Date getFirstDateOfWeek(Date weekDate) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(weekDate);
        calendar.add(
            Calendar.DAY_OF_WEEK,
            calendar.getFirstDayOfWeek() - calendar.get(Calendar.DAY_OF_WEEK));
        Date date = calendar.getTime();
        zeroTimeOfDate(date);
        return date;
    }

    /**
     * 获取指定日期的下一周第一天的日期，星期天为第一天
     * @param weekDate 周里任意一天的日期
     * @return Date 下一周第一天的日期
     */
    public static Date getFirstDateOfNextWeek(Date weekDate) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(weekDate);
        calendar.add(Calendar.DAY_OF_YEAR, 8 - calendar.get(Calendar.DAY_OF_WEEK));
        Date date = calendar.getTime();
        zeroTimeOfDate(date);
        return date;
    }

    /**
     * 获取指定日期所在的月的第一天的日期
     * @param monthDate 月里任意一天的日期
     * @return Date 第一天的日期
     */
    public static Date getFirstDateOfMonth(Date monthDate) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(monthDate);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        Date date = calendar.getTime();
        zeroTimeOfDate(date);
        return date;
    }

    /**
     * 获取指定日期的下一月第一天的日期
     * @param monthDate 月里任意一天的日期
     * @return Date 下一月第一天的日期
     */
    public static Date getFirstDateOfNextMonth(Date monthDate) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(monthDate);
        calendar.add(Calendar.MONTH, 1);
        Date date = calendar.getTime();
        zeroTimeOfDate(date);
        return date;
    }
    
    /**
     * 取上一天的日期
     * @return
     */
    public static Date getDateOfPrevDay(){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(currentDate());
        calendar.add(Calendar.DATE, -1);
        Date date = calendar.getTime();
        return date;
    }
    
    /**
     * 取下几天的日期
     * @param d
     * @param day
     * @return
     */
    public static Date getDateOfNexts(Date d,int day){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(d);
        calendar.add(Calendar.DATE, day);
        Date date = calendar.getTime();
        return date;                
    }
    
    /**
     * 取下几天的日期
     * @param day
     * @return
     */
    public static Date getDateOfNexts(int day){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(currentDate());
        calendar.add(Calendar.DATE, day);
        Date date = calendar.getTime();
        return date;        
    }

    /** 对日期里的时间进行清0，包括小时，分钟和秒*/
    private static void zeroTimeOfDate(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY,0);
        calendar.set(Calendar.MINUTE,0);
        calendar.set(Calendar.SECOND,0);
    }
    
    public static int getYear(Date date){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.YEAR);        
    }

    public static int getMonth(Date date){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.MONTH) + 1;        
    }
    
    /**
     * 返回今天的时间字符串（精确到天“yyyy-MM-dd”）
     * @return
     */
    public static String getTodayDateString(){
    	return DateHelper.toString(new Date(),DateHelper.LONG_DATE_FORMAT);
    }
    
    /**
     * 返回当前时间字符串（精确到秒"yyyy-MM-dd HH:mm:ss"）
     * @return
     */
    public static String getNowTimeString(){
    	return DateHelper.toString(new Date(),DateHelper.LONG_DATETIME_FORMAT);
    }
    
    /**
     * czqcs
     * @return 当前时间的小时和分钟（HH:mm）
     */
    public static String getNowHourAndMiTime(){
    	return DateHelper.toString(new Date(), "HH:mm");
    }
    
    /**
     * 功能：获取某个日期加N个月后得日期
     * @param date
     * @param month：可以为正整数也可以为负整数
     * @return
     */
    public static Date getDateAfterAddMonth(Date date, int month){
    	Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, month);
        Date date_new = calendar.getTime();
        return date_new;
    }
    
    public static int getYearAfterAddMonth(int year,int month,int n){
    	Calendar calendar = Calendar.getInstance();
    	calendar.set(year, month - 1, 1);
        calendar.add(Calendar.MONTH, n);
        return calendar.get(Calendar.YEAR);
    }
    
    public static int getMonthAfterAddMonth(int year,int month,int n){
    	Calendar calendar = Calendar.getInstance();
    	calendar.set(year, month - 1, 1);
        calendar.add(Calendar.MONTH, n);
        return calendar.get(Calendar.MONTH) + 1;
    }
    
    public static void main(String[] args) {
		System.out.println(getYearAfterAddMonth(2007,8,4) + ":" + getMonthAfterAddMonth(2007,8,4));
		System.out.println(getYearAfterAddMonth(2007,8,5) + ":" + getMonthAfterAddMonth(2007,8,5));
		System.out.println(DateHelper.getYearAfterAddMonth(2007,10,1));
	}

}
